﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace UnityTouchTable.Example
{
    /// <summary>
    /// 中心节点
    /// </summary>
    public class CenterNode : MonoBehaviour
    {
        #region const
        /// <summary>
        /// 主颜色
        /// </summary>
        private const string MAINCOLOR = "_MainColor";

        /// <summary>
        /// 强度
        /// </summary>
        private const string AMPLITUDE = "_EmissionFlickerAmplitude";

        /// <summary>
        /// 频率
        /// </summary>
        private const string FREQUENCY = "_EmissionFlickerFrequency";
        #endregion

        #region Field
        /// <summary>
        /// Transform集
        /// </summary>
        private Transform[] m_Transforms;

        /// <summary>
        /// 材质球
        /// </summary>
        [SerializeField]
        [Header("材质球")]
        private Material m_Material = default;

        /// <summary>
        /// 渐变颜色
        /// </summary>
        [SerializeField]
        [Header("渐变颜色")]
        private Gradient m_Gradient = default;

        /// <summary>
        /// 强度
        /// </summary>
        [SerializeField]
        [Header("强度")]
        [Range(0.5f, 30.0f)]
        private float m_Intensity = 1.0f;

        /// <summary>
        /// 呼吸间隔
        /// </summary>
        [SerializeField]
        [Header("呼吸间隔")]
        [Range(0.01f, 200.0f)]
        private float m_FlickerDuration = 3.0f;

        /// <summary>
        /// 节点半径
        /// </summary>
        [SerializeField]
        [Header("节点半径")]
        [Range(1.0f, 10.0f)]
        private float m_Radius = 1.0f;

        /// <summary>
        /// 计时器
        /// </summary>
        private float m_Timer;
        #endregion

        #region Property
        /// <summary>
        /// 获取节点半径
        /// </summary>
        public float Randius => this.m_Radius;
        #endregion

        private void OnEnable()
        {
            this.m_Timer = 0.0f;

            this.m_Material.SetColor(CenterNode.MAINCOLOR, this.m_Gradient.Evaluate(0.0f));
            this.m_Material.SetFloat(CenterNode.AMPLITUDE, this.m_Intensity);
            this.m_Material.SetFloat(CenterNode.FREQUENCY, this.m_FlickerDuration);
            this.transform.localPosition = Vector3.zero;
            this.transform.localEulerAngles = Vector3.zero;
            this.transform.localScale = Vector3.one;

            this.m_Transforms = this.GetComponentsInChildren<Transform>();
        }

        private void Update()
        {
            this.m_Timer += Time.deltaTime;
            float ratio = this.m_Timer / this.m_FlickerDuration;
            if (ratio >= 1.0f)
            {
                ratio = 1.0f;
                this.m_Timer = 0.0f;
            }

            this.m_Material.SetColor(CenterNode.MAINCOLOR, this.m_Gradient.Evaluate(ratio));
            this.m_Material.SetFloat(CenterNode.AMPLITUDE, this.m_Intensity);
            this.m_Material.SetFloat(CenterNode.FREQUENCY, this.m_FlickerDuration);

            for (int i = 0; i < this.m_Transforms.Length; i++)
            {
                float speed = (i + 1);
                float dir = (i % 2 == 0 ? 1.0f : -1.0f);
                speed *= speed * dir;
                if (this.m_Transforms[i] == this.transform)
                    continue;

                Transform transform = this.m_Transforms[i];
                float angle = transform.eulerAngles.z;
                angle += speed * Time.deltaTime;
                angle %= 360.0f;
                this.m_Transforms[i].eulerAngles = Vector3.forward * angle;
            }
        }

        private void OnDisable()
        {
            this.m_Timer = 0.0f;
            this.m_Material.SetColor(CenterNode.MAINCOLOR, this.m_Gradient.Evaluate(0.0f));
            this.m_Material.SetFloat(CenterNode.AMPLITUDE, this.m_Intensity);
            this.m_Material.SetFloat(CenterNode.FREQUENCY, this.m_FlickerDuration);

            System.Array.Clear(this.m_Transforms, 0, this.m_Transforms.Length);
            this.m_Transforms = null;
        }
    }
}